package com.supergo.service;

import com.alibaba.fastjson.JSON;
import com.supergo.config.GoodsMap;
import com.supergo.http.HttpResult;
import com.supergo.manager.feign.ApiGoodsFeign;
import com.supergo.manager.feign.ApiItemCatFeign;
import com.supergo.pojo.Goods;
import com.supergo.pojo.Goodsdesc;
import com.supergo.pojo.Item;
import com.supergo.pojo.Itemcat;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class PageService {

    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private ApiGoodsFeign goodsFeign;

    @Autowired
    private ApiItemCatFeign itemCatFeign;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private GoodsMap goodsLock;

    public HttpResult buildGoodsPage(Long goodsId) throws IOException{
        FileWriter fileWriter = new FileWriter("C:/template/page/" + goodsId + ".html");
        Context context = getGoodsData(goodsId);
        templateEngine.process("item", context, fileWriter);
        fileWriter.close();
        return HttpResult.ok();
    }

    private Context getGoodsData(Long goodsId) {
        Context context = new Context();
        //Goods
        Goods goods = goodsFeign.getGoodsById(goodsId);
        //查询商品的分类，三个分类
        Itemcat itemCat1 = itemCatFeign.getItemCatById(goods.getCategory1Id());
        Itemcat itemCat2 = itemCatFeign.getItemCatById(goods.getCategory1Id());
        Itemcat itemCat3 = itemCatFeign.getItemCatById(goods.getCategory1Id());
        //GoodsDesc
        Goodsdesc goodsdesc = goodsFeign.getGoodsDescById(goodsId);
        //获取图片列表
        String jsonImages = goodsdesc.getItemImages();
        if(StringUtils.isNotBlank(jsonImages)){
            try{
                List<Map> images = JSON.parseArray(jsonImages, Map.class);
                context.setVariable("itemImageList", images);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        //提取属性信息
        String jsonCustomAttributeItems = goodsdesc.getCustomAttributeItems();
        if(StringUtils.isNotBlank(jsonCustomAttributeItems)){
            try{
                List<Map> customeAttributeItems = JSON.parseArray(jsonCustomAttributeItems, Map.class);
                context.setVariable("customAttributeItems", customeAttributeItems);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        //提取规格数据
        String jsonSpecificationItems = goodsdesc.getSpecificationItems();
        if (StringUtils.isNotBlank(jsonSpecificationItems)) {
            try {
                List<Map> specificationItems = JSON.parseArray(jsonSpecificationItems, Map.class);
                context.setVariable("specificationList", specificationItems);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // List<Item>
        List<Item> itemList = goodsFeign.getItemList(goodsId);
        context.setVariable("goods", goods);
        context.setVariable("goodsDesc", goodsdesc);
        context.setVariable("itemCat1", itemCat1);
        context.setVariable("itemCat2", itemCat2);
        context.setVariable("itemCat3", itemCat3);
        context.setVariable("itemList", itemList);
        return context;
    }

    /**
     * 查询spu商品库存
     * @param goodsId
     * @return
     */
    public Map<Object, Object> getItemsStock(long goodsId) {
        //防止缓存穿透，非法id直接返回
        if(goodsId <= 0){
            Map<Object, Object> result = new HashMap<>();
            result.put("0", 0);
            return result;
        }

        //先获得锁, 获得goodsId对应的lock, 保证只能有一个线程访问同一个商品
        ReentrantLock lock = goodsLock.getLock(goodsId);
        if(lock.tryLock()){
            //查询数据库
            List<Item> itemList = goodsFeign.getItemList(goodsId);
            //判断数据库中查不到数据的话，添加空值缓存，防止缓存穿透
            if(itemList == null || itemList.isEmpty()){
                // 将空数据进行缓存起来
                redisTemplate.opsForHash().put("goodsstock:" + goodsId, "0", "0");
                redisTemplate.expire("goodsstock:" + goodsId, 1, TimeUnit.MINUTES);
                Map<Object, Object> result = new HashMap<>();
                result.put("0", "0");
                return result;
            }
            Map<Object, Object> result = new HashMap<>();
            itemList.forEach(item -> {
                result.put(item.getId(), item.getNum());
                //添加到缓存
                redisTemplate.opsForHash().put("goodsstock:" + goodsId, item.getId().toString(), item.getNum().toString());
            });
            //提高缓存的利用率设置缓存的过期时间
            redisTemplate.expire("goodsstock:" + goodsId, 1, TimeUnit.DAYS);
            //释放锁
            lock.unlock();
            //全局锁释放
            goodsLock.removeLock(goodsId);
            return result;
        }else{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return getItemsStock(goodsId);
        }

    }

}
